/**
 * Copyright(C): CETC-32
 * @Title: CenterAuthShiroConfig
 * @Description: Shiro安全认证
 * @author: youqing
 * @version: 1.0
 * @date: 2020/9/11 10:55
 * 更改描述：
 */

package com.cetc32.dh.common.shiro;

import com.cetc32.dh.common.filter.JWTFilter;
import org.apache.shiro.cas.CasFilter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.DelegatingFilterProxy;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Token检查类
 * @Title: FormFilter
 * @version: 1.0
 * @date: 2020/9/11 10:55
 */
@Configuration
public class CenterAuthShiroConfig {

//    //cas server地址
//    public static final String casServerUrlPrefix="http://www.cetc.daohang.com:9100/cas";
//
//    //cas登录页面地址
//    public static final String casLoginUrl = casServerUrlPrefix + "/login";
//
//    //cas登出页面地址
//    public static final String casLogoutUrl = casServerUrlPrefix + "/logout";
//
//    //当前工程对外提供的服务地址
//    public static final String shiroServerUrlPrefix = "http://localhost:9100";
//
//    //casFilter UrlPattern
//    public static final String casFilterUrlPattern = "/cas";
//
//    //登录地址
//    public static final String loginUrl = casLoginUrl + "?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
//
//    // 登出地址（casserver启用service跳转功能，需在webapps\cas\WEB-INF\cas.properties文件中启用cas.logout.followServiceRedirects=true）
//    public static final String logoutUrl = casLogoutUrl + "?service=" + shiroServerUrlPrefix;
//
//    //登录成功地址
//    public static final String loginSuccessUrl = "/user";
//
//    //限认证失败跳转地址
//    public static final String unauthorizedUrl = "/403.html";
//
//    @Value("${jedis.pool.host}")
//    private String host;
//
//    @Value("${jedis.pool.port}")
//    private int port;


    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager securityManager(CenterAuthRealm centerAuthRealm){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        // 设置自定义 realm.
        securityManager.setRealm(centerAuthRealm);

        //关闭session
        DefaultSubjectDAO subjectDAO=new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator sessionStorageEvaluator=new DefaultSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        return securityManager;
    }

//    /**
//     * 注册单点登出listener
//     *
//     * @return
//     */
//    @Bean
//    @Order(Ordered.HIGHEST_PRECEDENCE)
//    public ServletListenerRegistrationBean singleSignOutHttpSessionListener() {
//        ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean();
//        bean.setListener(new SingleSignOutHttpSessionListener());
//        bean.setEnabled(true);
//        return bean;
//    }
//
//    /**
//     * 注册单点登出filter
//     *
//     * @return
//     */
//    @Bean
//    public FilterRegistrationBean singleSignOutFilter() {
//        FilterRegistrationBean bean = new FilterRegistrationBean();
//        bean.setName("singleSignOutFilter");
//        bean.setFilter(new SingleSignOutFilter());
//        bean.addUrlPatterns("/*");
//        bean.setEnabled(true);
//        return bean;
//    }
//
//    /**
//     * 注册DelegatingFilterProxy（Shiro）
//     *
//     * @return
//     */
//    @Bean
//    public FilterRegistrationBean delegatingFilterProxy() {
//        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
//        filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
//        //  该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
//        filterRegistration.addInitParameter("targetFilterLifecycle", "true");
//        filterRegistration.setEnabled(true);
//        filterRegistration.addUrlPatterns("/*");
//        return filterRegistration;
//    }

//    /**
//     * CAS过滤器
//     *
//     * @return
//     */
//    @Bean(name = "casFilter")
//    public CasFilter getCasFilter() {
//        CasFilter casFilter = new CasFilter();
//        casFilter.setName("casFilter");
//        casFilter.setEnabled(true);
//        // 登录失败后跳转的URL，也就是 Shiro 执行 CasRealm 的 doGetAuthenticationInfo 方法向CasServer验证tiket
//        casFilter.setFailureUrl(loginUrl);// 我们选择认证失败后再打开登录页面
//        casFilter.setSuccessUrl(loginSuccessUrl);
//        return casFilter;
//    }



    /**
     * 先走 filter ，然后 filter 如果检测到请求头存在 token，则用 token 去 login，走 Realm 去验证
     */
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @Bean
    public ShiroFilterFactoryBean factory(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean=new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        // &#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684;&#x8FC7;&#x6EE4;&#x5668;&#x5E76;&#x4E14;&#x53D6;&#x540D;&#x4E3A;jwt
        Map<String, Filter> filterMap=new LinkedHashMap<>();
        //设置我们自定义的JWT过滤器
        filterMap.put("jwt",new JWTFilter());
        factoryBean.setFilters(filterMap);

        // 设置无权限时跳转的 url;
        factoryBean.setUnauthorizedUrl("/unauthorized/无权限");
        Map<String,String> filterRuleMap=new HashMap<>();
        // 所有请求通过我们自己的JWT Filter
        filterRuleMap.put("/**","jwt");
        // 访问 /unauthorized/** 不通过JWTFilter
        filterRuleMap.put("/unauthorized/**","anon");
        filterRuleMap.put("/open/**","anon");
        //filterRuleMap.put("/rest/**","anon");
        factoryBean.setFilterChainDefinitionMap(filterRuleMap);
        return factoryBean;
    }


    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }



    /**
     * 添加注解支持，如果不加的话很有可能注解失效
     */
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @Bean
   // @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){

        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){

        AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }



}